<?php

declare(strict_types=1);
/**
 * Author: Zane
 * Email: 873934580@qq.com
 * Date: 2022/5/26.
 */

namespace Zane\View\Compiler;

use Illuminate\Support\Arr;
use Illuminate\Support\Str;

class ParamParse
{
    use ParseTrait;

    private $expression;
    private $empty = '';
    private $id = '$field';
    private $encoding = 'UTF-8';
    private $result = [];

    private function __construct($expression)
    {
        $this->expression = $expression;
        if (!$this->expression) {
            return;
        }
        $this->eraseBracketNoise();
        $this->parse();
    }

    public static function make($expression): self
    {
        return new self($expression);
    }

    /**
     * 空字符串展示内容.
     *
     * @return string
     */
    public function getEmpty(): string
    {
        return $this->result['empty'] ?? config('view.empty', '');
    }

    /**
     * 迭代器字段名称.
     *
     * @return string
     */
    public function getIteration(): string
    {
        if (isset($this->result['id'])) {
            return Str::start($this->result['id'], '$');
        }

        return $this->id;
    }

    /**
     * 解析表达式.
     *
     * @return string
     */
    public function getExpression(): string
    {
        if (!$this->result) {
            return '\\Zane\\View\\Service\\Transfer::build()';
        }
        $keys = array_keys($this->result);
        $sorted = Arr::sort($keys);
        $result = '';
        $exclude = ['empty', 'id'];
        foreach ($sorted as $key) {
            if (\in_array($key, $exclude, true)) {
                continue;
            }
            $str = $this->result[$key];
            if (!Str::startsWith($str, ['$', '['])) {
                $str = "'{$str}'";
            }

            $str = "'{$key}' => {$str}";

            $result = '' === $result ? $str : $result.', '.$str;
        }

        return "\\Zane\\View\\Service\\Transfer::build([{$result}])";
    }

    /**
     * 去除多余的括号.
     */
    private function eraseBracketNoise(): void
    {
        $this->expression = mb_substr($this->expression, 1, mb_strlen($this->expression) - 2, $this->encoding);
    }
}
